package br.com.unitunes.model;

import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;

@Entity(name="MIDIA")
@Inheritance(strategy=InheritanceType.JOINED)
@SequenceGenerator(sequenceName = "MIDIA_SEQ", name = "MIDIA_SEQ", allocationSize=1, initialValue = 1)
public abstract class Midia extends GenericModel{
	
	@Id
	@Column(name = "MIDIA_ID")
	@GeneratedValue(generator = "MIDIA_SEQ", strategy = GenerationType.SEQUENCE)
	protected Long id;
	
    @ManyToOne
    @JoinColumn(name = "AUTOR_ID")
    protected Usuario autor;

	@Column(name = "NOME", length = 50, nullable = false)	
	protected String nome;

	@Column(name = "DESCRICAO", length = 400, nullable = true)	
	protected String descricao;

	@Column(name = "PRECO", nullable = true)
	protected Double preco;
		
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "DATA_CREATE", nullable = true)
    protected Date dataCreate;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "DATA_UPDATE", nullable = true)
    protected Date dataUpdate;
    
	@Enumerated(EnumType.STRING)
	private Status status = Status.ATIVO;
    
	@OneToMany(fetch = FetchType.LAZY, mappedBy = "midia")
	private List<MidiaComprada> midiasCompradas;
	
    @PrePersist
    protected void onCreate() {
    	dataCreate = dataUpdate = new Date();
    }

    @PreUpdate
    protected void onUpdate() {
    	dataUpdate = new Date();
    }	
    
	public Date getDataCreate() {
		return dataCreate;
	}

	public void setDataCreate(Date dataCreate) {
		this.dataCreate = dataCreate;
	}

	public Date getDataUpdate() {
		return dataUpdate;
	}

	public void setDataUpdate(Date dataUpdate) {
		this.dataUpdate = dataUpdate;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Usuario getAutor() {
		return autor;
	}

	public void setAutor(Usuario autor) {
		this.autor = autor;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public Double getPreco() {
		return preco;
	}

	public void setPreco(Double preco) {
		this.preco = preco;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}
	
	public boolean isActive()
	{
		return getStatus().equals(Status.ATIVO);
	}
	
	public boolean isInactiveByAdmin()
	{
		return getStatus().equals(Status.DES_ADIMIN);
	}
	
	public boolean isInactiveByUser()
	{
		return getStatus().equals(Status.DES_AUTOR);
	}
	
	public boolean autorIgual(Usuario usuario)
	{
		if(usuario == null) return false;
		return this.getAutor().getId().equals(usuario.getId());
	}
	
	public void desativaMidia(Usuario usuario)
	{
		if(usuario == null) return;
		if(!this.isActive()) return;
		
		if(this.autorIgual(usuario)) this.status = Status.DES_AUTOR;
		if(usuario.getPerfil().equals(Perfil.ADMINISTRADOR)) this.status = Status.DES_ADIMIN;
	}
	
	public void ativaMidia(Usuario usuario)
	{
		if(usuario == null) return;
		
		if((this.isInactiveByUser() && this.autorIgual(usuario)) || usuario.getPerfil().equals(Perfil.ADMINISTRADOR)) 
			this.status = Status.ATIVO;
	}
}
